﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Implementation;
using interfaces;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Threading;
using System.Threading;



namespace civilizationWPF
{
    /// <summary>
    /// \file MainWindow.cs
    /// \brief gere le jeu et son affichage
    /// </summary>
    public partial class MainWindow : Window
    {
        Jeu j;
        UniteImpl uniteSelect;
        Ville villeSelect;
        Dictionary<UniteImpl, Ellipse> Dico_UnitToEll;//asocie l'unité à l'ellipse la représentant sur la carte
        Slash screen;//pour le splash screen
        FabriqueTexture textures;

        public MainWindow(Jeu jeu)
        {
            textures = new FabriqueTexture();
            Dico_UnitToEll = new Dictionary<UniteImpl, Ellipse>();
            j = jeu;
            InitializeComponent();
        }

        /**
         * \fn buttonFinTour_Click
         * \brief evenement generer en cas de fin de tour gere les actions associé
         */ 
        private void buttonFinTour_Click(object sender, RoutedEventArgs e)
        {
            bool victoire = j.faireTour(j.getJoueurCourant());
            if (victoire)
            {
                MessageBoxResult result = MessageBox.Show(this, "VICTOIRE !! \n en "+j.getJoueurCourant().getNbTour()+" tours");
                
                Window w = new MenuWindow();
                w.Visibility = Visibility;
                this.Close();
            }
            //netoyage
            foreach (KeyValuePair<UniteImpl,Ellipse> keypair in Dico_UnitToEll)
            {
                Ellipse ell = keypair.Value;
                ell.Visibility = Visibility.Collapsed;
                ell = null;
            }
            Dico_UnitToEll.Clear();

            clearInterface();
            selectionRectangle.Visibility = Visibility.Hidden;

            //update de l'interface pour le joueur suivant
            jouons();
            updateVilleUI();
            updateUnitUI();

        }

        /**
         * \fn SlashHandler()
         * \brief gere le splash screen dans un nouveau thread
         */ 
        private Thread SlashHandler()
        {
            Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
            newWindowThread.SetApartmentState(ApartmentState.STA);
            newWindowThread.IsBackground = true;
            newWindowThread.Start();
            return newWindowThread;
        }

        /**
         * \fn ThreadStartingPoint()
         * \brief depart du nouveau thread pour le splash screen
         */
        private void ThreadStartingPoint()
        {
            screen = new Slash();
            screen.Show();
            screen.action();
            System.Windows.Threading.Dispatcher.Run();
        }

        /**
         * \fn Window_Loaded()
         * \brief event generer quand la fenetre est chargé => splash screen + mise en place de l'interface
         */
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Thread nwt = SlashHandler();//splash screen
            //creation de la grille de la carte
            int t = j.getCarte().getTaille();
            CarteImpl lc = j.getCarte();

            for (int c = 0; c < t; c++)
            {
                Map.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(40, GridUnitType.Pixel) });
            }

            for (int l = 0; l < t; l++)
            {
                Map.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(40, GridUnitType.Pixel) });

                for (int c = 0; c < t; c++)
                {
                    string type = lc.getCase(c, l).getType();
                    if (type == "fer" || type == "fruit")
                    {
                        DecorateurResource dr = (DecorateurResource)lc.getCase(c, l);
                        type = dr.getCase().getType();
                    }
                    int r = new Random().Next(0, 3);
                    
                    var rect = create_rectangle(c, l, type);
                    Map.Children.Add(rect);

                    type = lc.getCase(c, l).getType();
                    create_ressource(c, l, type);
                    
                }
            }
            //ajout des unités / villes
            updateVilleUI();
            updateUnitUI();
            jouons();
            nwt.Abort();//fin du splash screen
        }

        /**
         * \fn jouons
         * \brief modifie le joueur courant
         */
        public void jouons()
        {
           
            Implementation.Joueur jc = j.getJoueurCourant();
            nom_joueur_courant.Content = jc.getNom();
            compteurTour.Content = jc.getNbTour() + 1;
            updateScroll(jc);
        }

        private void updateScroll(Implementation.Joueur jc)
        {
            if (jc.getCivilisation().getUnites().Any())
            {
                double ratiox = (double)jc.getCivilisation().getUnites()[0].getX() / (double)jc.getJeu().getCarte().getTaille();
                double ratioy = (double)jc.getCivilisation().getUnites()[0].getY() / (double)jc.getJeu().getCarte().getTaille();
                double width = (ScrollViewerMap.ScrollableWidth == 0.0) ? 0.0 : ScrollViewerMap.ScrollableWidth;
                double height = (ScrollViewerMap.ScrollableHeight == 0.0) ? 2000.0 : ScrollViewerMap.ScrollableHeight;
                ScrollViewerMap.ScrollToHorizontalOffset(ratiox * width);
                ScrollViewerMap.ScrollToVerticalOffset(ratioy * height);
            }
        }

        /**
         * \fn create_ressource
         * \brief rajoute les textures de ressources si il y a lieu
         * \param c : int la colonne
         * \param l : int la ligne
         * \param type : string le type de ressource
         */
        private void create_ressource(int c, int l, string type)
        {
            var rec = new System.Windows.Shapes.Rectangle();
            switch (type)
            {
                case "fer": rec.Fill = textures.ferBrush; break;
                case "fruit": rec.Fill = textures.fruitBrush; ; break;
                default: return;
            }
            
            Grid.SetColumn(rec, c);
            Grid.SetRow(rec, l);
            // source = rectangle / evt = MouseLeftButtonDown / délégué = rectangle_MouseLeftButtonDown
            rec.MouseLeftButtonDown += new MouseButtonEventHandler(rectangle_MouseLeftButtonDown);
            Map.Children.Add(rec);
        }

        /**
         * \fun create_rectangle
         * \bief cree les rectangles avec textures de la map
         * \param1 c : int la colonne
         * \param2 l : int la ligne
         * \param3 type : string le type de terrain
         * \return Rectangle
         */
        private System.Windows.Shapes.Rectangle create_rectangle(int c, int l, string type)
        {
            var rectangle = new System.Windows.Shapes.Rectangle();
            
            switch (type)
            {
                case "plaine": rectangle.Fill = textures.plaineBrush; break;
                case "montagne": rectangle.Fill = textures.montBrush; break;
                case "desert": rectangle.Fill = textures.desertBrush; break;
                default: rectangle.Fill = textures.plaineBrush; break;
            }
            Grid.SetColumn(rectangle, c);
            Grid.SetRow(rectangle, l);
            rectangle.Tag = type;
            // source = rectangle / evt = MouseLeftButtonDown / délégué = rectangle_MouseLeftButtonDown
            rectangle.MouseLeftButtonDown += new MouseButtonEventHandler(rectangle_MouseLeftButtonDown);
            return rectangle;
        }

        /**
         * \fn updateUnitUi()
         * \brief affiche les unités sur la carte
         */ 
        private void updateUnitUI()
        {
            Implementation.Joueur jou = j.getJoueurCourant();
            List<Unite> us = jou.getCivilisation().getUnites();
            foreach (Unite u in us)
            {
                afficheUnite((UniteImpl) u, jou);
                vueUniteEnemie(u.getX(), u.getY(), jou, 2);
            }

         }

        /**
         * \fn afficheUnite
         * \brief gere l'affichage d'une unité
         * \param[in] UniteImpl
         * \param[in] Joueur
         */ 
        private void afficheUnite(UniteImpl u, Implementation.Joueur jou)
        {
            Ellipse c;
            bool exist = false;
            if (Dico_UnitToEll.ContainsKey(u))
            {
                c = Dico_UnitToEll[u];
                exist = true;
            }
            else
            {
                c = new Ellipse();
                c.MouseLeftButtonDown += new MouseButtonEventHandler(ellipse_MouseLeftButtonDown);
            }

            switch (jou.getColor())
            {
                case "red": c.Fill = System.Windows.Media.Brushes.Red; break;
                case "blue": c.Fill = System.Windows.Media.Brushes.Blue; break;
                case "green": c.Fill = System.Windows.Media.Brushes.Green; break;
                case "white": c.Fill = System.Windows.Media.Brushes.White; break;
            }
            c.Width = 10;
            c.Height = 10;
            Grid.SetColumn(c, u.getX());
            Grid.SetRow(c, u.getY());
            if (!exist)
            {
                Dico_UnitToEll[u] = c;
                Map.Children.Add(c);
            }
           
        }

        /**
         * \fn updateVilleUI
         * \brief gere l'affichage des ville
         */ 
        private void updateVilleUI()
        {
            List<Implementation.Joueur> playeurs = j.getJoueurs();
            Implementation.Joueur jou = j.getJoueurCourant();
            bool jc = false;

            foreach (Implementation.Joueur p in playeurs)
            {
                jc = (jou == p)? true : false;//savoir si le joueur dont on affiche les villes est le joueur courant
                List<Ville> villes = p.getCivilisation().getVilles();
                foreach (Ville v in villes)
                {
                    affichage_ville(jc, jou, v);
                }

            }
        }

        /**
         * \fn affichage_ville
         * \brief affiche une ville
         * \param[in] bool si c'est la ville du joueur cournat
         * \param[in] Joueur
         * \param[in] Ville
         */ 
        private void affichage_ville(bool jc, Implementation.Joueur jou, Ville v)
        {
            int[][] exp = v.getExpansion();
            for (int i = 0; i < 25; i++)
            {
                if (exp[i][0] != -1)
                {
                    var rec = new System.Windows.Shapes.Rectangle();
                    rec.Fill = textures.villeBrush;
                    Grid.SetColumn(rec, exp[i][0]);
                    Grid.SetRow(rec, exp[i][1]);
                    rec.MouseLeftButtonDown += new MouseButtonEventHandler(rectangle_MouseLeftButtonDown);
                    if ((exp[i][0] == v.getX()) && (exp[i][1] == v.getY()))
                    {
                        rec.Stroke = couleur_ville(v);
                        rec.StrokeThickness = 1;
                    }

                    Map.Children.Add(rec);

                    if (jc)
                        vueUniteEnemie(v.getX(), v.getY(), jou, 3);
                }
            }
        }

        private System.Windows.Media.SolidColorBrush couleur_ville(Ville v)
        {
            switch (v.getJoueur().getColor())
            {
                case "red": return System.Windows.Media.Brushes.Red;
                case "blue": return System.Windows.Media.Brushes.Blue;
                case "green": return System.Windows.Media.Brushes.Green;
                default: return System.Windows.Media.Brushes.White;
            }
        }

        /**
         * \fn vueUniteEnemie
         * \brief regarde si on voit des unités enemie
         * \param[in] int
         * \param[in] int
         * \param[in] Joueur
         * \param[in] int distance de vue
         */ 
        private void vueUniteEnemie(int x, int y, Implementation.Joueur jou, int cir)
        {
            int i = x - cir;
            i = (i > 0) ? i : 0;

            int j = y - cir;
            j = (j > 0) ? j : 0;

            int tcarte = this.j.getCarte().getTaille();
            for (; (i < x + cir) && i < tcarte; i++)
            {
                for (; (j < y + cir) && j < tcarte ; j++)
                {
                    List<Unite> ue = this.j.getUnitePosition(i, j);
                    if (ue != null)
                    {
                        foreach (UniteImpl u in ue)
                        {
                            if (u.getJoueur() != jou)
                            {
                                afficheUnite(u, u.getJoueur());
                            }//if
                        }//foreach
                    }
                }//for1 
                j = y - cir;
                j = (j > 0) ? j : 0;
            }//for2
        }

        //les evenements lié aux menu
        private void Sauver_Click_1(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.FileName = "Document"; // Default file name
            dlg.DefaultExt = ".sauv"; // Default file extension 
            // Show open file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process open file dialog box results
            if (result == true)
            {
                // Open document
                string filename = dlg.FileName;
                Jeu.saveGame(filename, j);
            }
            
        }
        private void Charger_Click_1(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.FileName = "Document"; // Default file name
            dlg.DefaultExt = ".sauv"; // Default file extension 
            // Show open file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process open file dialog box results
            if (result == true)
            {
                // Open document
                string filename = dlg.FileName;
                Jeu jeu = Jeu.loadGame(filename);
                Window w = new MainWindow(jeu);
                w.Visibility = Visibility;
                this.Close();
            }
            
        }
        private void Quitter_Click_1(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show(this, "Voulez vous quitter?", "Quitter?", MessageBoxButton.YesNo);
            if (result == MessageBoxResult.Yes)
                this.Close();
        }
        private void Controles_Click_1(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show(this, "Selectionne une case, utilise les fléches directionnelles pour déplacer tes unités ...", "Controles");
        }
        private void Regles_Click_1(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show(this, "L'INSA est en guerre soldat!\n Choisit ton département et bat toi!\n Les enseignants permettent de creer des nouvelles villes, les étudiants d'exterminer tes oposants et les Directeur de booster le moral de vos troupes.\n Lorsque vous n'avez plus de ville ou d'enseigant vous avez perdue...\n\n Maintenant que tu sais tout au combat soldat!", "Régles");
        }
        private void A_Propos_Click_1(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show(this, "Jeu Civilinsation réalisé par : \n Sylvain Favre et L'honoré Vincent");
        }

        /**
         * \fn clearInterface
         * \brief fait tt disparaitre
         */ 
        private void clearInterface()
        {
            Info_ville.Visibility = Visibility.Hidden;
            Info_Unite.Visibility = Visibility.Hidden;
            Info_Terrain.Visibility = Visibility.Hidden;
            uniteSelect = null;
            villeSelect = null;
            suggestionville1.Visibility = System.Windows.Visibility.Hidden;
            suggestionville2.Visibility = System.Windows.Visibility.Hidden;
            suggestionville3.Visibility = System.Windows.Visibility.Hidden;
        }

        private void ellipse_MouseLeftButtonDown(Object sender, RoutedEventArgs e)
        {
            e.Handled = true;
        }

        /**
         * \fn rectangle_MouseLeftButtonDown
         * \brief event generer qd click sur rectangle de la map => affichage de diferente chose suivnat ce qu'il y a sur la carte
         */ 
        private void rectangle_MouseLeftButtonDown(Object sender, RoutedEventArgs e)
        {
            var rectangle = sender as System.Windows.Shapes.Rectangle;
            //on recupére les coordonées
            int column = Grid.GetColumn(rectangle);
            int row = Grid.GetRow(rectangle);
            updateRectangleSelection(column, row);//on affcihe le rec de selection

            clearInterface();//on nettoye
            //update de l'interface suivant ce qu'il y a dessus
            List<Unite> lu = j.getUnitePosition(column, row);
            Ville lv = j.getVillePosition(column, row);
            if (lu == null && lv != null)
                updateSelectedTown(column, row, lv);
            else if (lu != null)
            {
                // updateSelectedUnit(column, row);
                if (lu.Count == 1 && lv == null && lu[0].getJoueur() == j.getJoueurCourant())
                    updateSelectedUnit(column, row, lu[0]);
                else if (!lu.Any() && lv != null)
                    updateSelectedTown(column, row, lv);//oui c'est vraiment crade mais bon j'ai la flemme 
                else 
                    updateSelectedTerrain(column, row, lu, lv);
            }
            else
                updateSelectedTerrain(column, row,lu,lv);
            e.Handled = true;
        }

        /**
         * \fn updateRectangleSelection
         * \param[in] int x
         * \param[in] int y
         */
        private void updateRectangleSelection(int x, int y)
        {
            Grid.SetColumn(selectionRectangle, x);
            Grid.SetRow(selectionRectangle, y);
            selectionRectangle.Visibility = System.Windows.Visibility.Visible;
        }

        private void window_MouseLeftButtonDown(Object sender, RoutedEventArgs e)
        {
            selectionRectangle.Visibility = System.Windows.Visibility.Collapsed;
        }

        /**
         * \fn updateSelectedUnit
         * \brief affichage de l'interface unit
         * \param[in] int c
         * \param[in] int r
         * \param[in] Unite
         */
        private void updateSelectedUnit(int c, int r, Unite u)
        {

            Info_ville.Visibility = Visibility.Hidden;
            Info_Unite.Visibility = Visibility.Visible;
            Info_Unite_Button_Enseignant.Visibility = Visibility.Hidden;

            string nom = "";
            if (u is Etudiant)
                nom = "Etudiant";
            else if (u is Enseignant)
            {
                Info_Unite_Button_Enseignant.Visibility = Visibility.Visible;
                nom = "Enseignant";
            }
            else
                nom = "Directeur";

            Info_Unite_Nom.Content = nom;
            uniteSelect = (UniteImpl)u;
            Info_Unite_pt_vie.Content = uniteSelect.getVie();
            Info_Unite_pt_att.Content = uniteSelect.getAtt();
            Info_Unite_pt_def.Content = uniteSelect.getDef();
            Info_Unite_pt_mvt.Content = uniteSelect.nbPtMvtRestant();

        }

        /**
         * \fn updateSelectedTown
         * \brief affichage de l'interface unit
         * \param[in] int c
         * \param[in] int r
         * \param[in] Ville
         */
        private void updateSelectedTown(int c, int r, Ville v)
        {
            if (v.getJoueur() != j.getJoueurCourant())//si la ville appartient pas au joueur courant on affiche juste le terrain sur laquel elle est
            {
                updateSelectedTerrain(c, r, null, null);
                return;
            }
            int minerai = v.getMinerai();
            Info_ville.Visibility = Visibility.Visible;
            Info_ville_minerai.Content = minerai;
            Info_ville_nourriture.Content = v.getNourriture();
            Info_ville_population.Content = v.getPopulation();
            Info_ville_nom.Content = v.getName();
            villeSelect = v;
            creation_unite.SelectedIndex = -1;
            creation_unite.IsEnabled = true;
            creation_unite_directeur.IsEnabled = true;
            creation_unite_etudiant.IsEnabled = true;

            if (minerai < CivilisationImpl.COUT_ENSEIGNANT)
                creation_unite.IsEnabled = false;
            else
            {
                if (minerai < CivilisationImpl.COUT_DIRECTEUR || j.getJoueurCourant().getCivilisation().aDirecteur())
                    creation_unite_directeur.IsEnabled = false;
                if (minerai < CivilisationImpl.COUT_ETUDIANT)
                    creation_unite_etudiant.IsEnabled = false;
            }
        }

        /**
         * \fn updateSelectedTerrain
         * \brief affichage de l'interface terrain
         * \param[in] int c
         * \param[in] int r
         * \param[in] List<Unite> lu
         * \param[in] Ville
         */
        private void updateSelectedTerrain(int c, int r, List<Unite> lu, Ville v)
        {
            Info_Terrain.Visibility = Visibility.Visible;
            Info_Terrain_minerai.Content = j.getCarte().getMinerai(c, r);
            Info_Terrain_nourriture.Content = j.getCarte().getNouriture(c, r);
            liste_chose_sur_pos.Items.Clear();
            liste_chose_sur_pos.IsEnabled = false;

            ComboBoxItem cbi;
            if (v != null)
            {
                cbi = new ComboBoxItem();
                cbi.Content = v.getName();
                liste_chose_sur_pos.Items.Add(cbi);
                liste_chose_sur_pos.IsEnabled = true;
            }
            if (lu != null && lu.Any())
            {
                liste_chose_sur_pos.IsEnabled = true;
                foreach (Unite u in lu)
                {
                    if (u.getJoueur() == j.getJoueurCourant())
                    {
                        cbi = new ComboBoxItem();
                        if (u is Etudiant)
                            cbi.Content = "Etudiant";
                        else if (u is Enseignant)
                            cbi.Content = "Enseignant";
                        else if (u is Directeur)
                            cbi.Content = "Directeur";
                        liste_chose_sur_pos.Items.Add(cbi);
                    }
                    else//si il y a des unité enemies ont ne peut pas les selectionner
                    {
                        liste_chose_sur_pos.IsEnabled = false;
                        break;
                    }
                }
            }
            
        }

        /**
         * \fn Window_keyDown
         * \brief event si keydown => mouvement unité ou fin tour
         */ 
        private void Window_KeyDown(Object sender, KeyEventArgs e)
        {
            if (uniteSelect != null)//si c'est null c'est qu'on a pas selectionné une unit
            {
                int nx;
                int ny;
                switch (e.Key)//calcul position futur
                {
                    case Key.Left:
                        nx = uniteSelect.getX() - 1;
                        ny = uniteSelect.getY();
                        break;
                    case Key.Right:
                        nx = uniteSelect.getX() + 1;
                        ny = uniteSelect.getY();
                        break;
                    case Key.Up:
                        nx = uniteSelect.getX();
                        ny = uniteSelect.getY() - 1;
                        break;
                    case Key.Down:
                        nx = uniteSelect.getX();
                        ny = uniteSelect.getY() + 1;
                        break;
                    default: nx = uniteSelect.getX();
                        ny = uniteSelect.getY(); break;
                }

                if (uniteSelect.deplacementValide(nx, ny))//deplacement
                {
                    uniteSelect.deplacement(nx, ny);
                    Info_Unite_pt_mvt.Content = uniteSelect.nbPtMvtRestant();
                    afficheUnite(uniteSelect, j.getJoueurCourant());
                    updateRectangleSelection(uniteSelect.getX(), uniteSelect.getY());
                    vueUniteEnemie(uniteSelect.getX(), uniteSelect.getY(), j.getJoueurCourant(), 2);
                }
                else if (uniteSelect is Etudiant && uniteSelect.nbPtMvtRestant() > 0)//attaque
                {
                    Etudiant etdt = (Etudiant)uniteSelect;
                    Ellipse ell = Dico_UnitToEll[uniteSelect];
                    Ellipse ellDef = ellipseDefenseur(uniteSelect, nx, ny);
                    bool success = etdt.attaquer(nx, ny);
                    if (success)
                    {
                        //if(!j.getUnitePosition(nx, ny).Any())
                            //uniteSelect.deplacement(nx, ny);
                        if(ellDef != null)
                            ellDef.Visibility = Visibility.Collapsed;//disparition de l'enemie
                        rapport_combat("Vous avez gagné ce combat, un petit pas de plus vers la victoire totale!");
                    }
                    if (etdt.getVie() == 0)
                    {
                        clearInterface();
                        ell.Visibility = Visibility.Collapsed;
                        uniteSelect = null;
                        selectionRectangle.Visibility = Visibility.Hidden;
                        rapport_combat("Votre unité est morte en combatant avec bravoure l'enemie...");
                    }
                    else
                    {
                        //mise à jour interface + rectangle selection
                        updateSelectedUnit(uniteSelect.getX(), uniteSelect.getY(), uniteSelect);
                        afficheUnite(uniteSelect, j.getJoueurCourant());
                        updateRectangleSelection(uniteSelect.getX(), uniteSelect.getY());
                        vueUniteEnemie(uniteSelect.getX(), uniteSelect.getY(), j.getJoueurCourant(), 2);
                        if(!success)
                            rapport_combat("Votre unité a subit des blessures mais elle est toujours en etat de se battre...");
                    }
                }
            }
            else if (e.Key == Key.Enter)//fin tour
                buttonFinTour_Click(sender, e);
            e.Handled = true;
        }

        //choix du défenseur, à savoir celui qui a la défense la plus élevée
        private Ellipse ellipseDefenseur(Unite att, int x, int y)
        {
            List<Unite> defs = att.getJoueur().getJeu().getUnitePosition(x, y);
            if (defs == null || !defs.Any())
                return null;

            UniteImpl tmp = (UniteImpl)defs.First();
            foreach (UniteImpl u in defs)
            {
                if (u.getDef() > tmp.getDef())
                    tmp = u;
            }
            return Dico_UnitToEll[tmp];
        }
        /**
         * \fn rapport_combat
         * \brief affiche le rapport de combat
         * \param[in] string le rapport
         */
        private void rapport_combat(string texte)
        {
            MessageBoxResult result = MessageBox.Show(this, texte, "Rapport de combat");
        }

        /**
         * \fn Creer_Ville_Click
         * \brief event creer ville
         */ 
        private void Creer_Ville_Click(Object sender, RoutedEventArgs e)
        {
            if (uniteSelect is Enseignant)
            {
                Enseignant en = (Enseignant)uniteSelect;
                Ville ville = en.creerVille();
                if (ville == null)
                {
                    MessageBoxResult result = MessageBox.Show(this, "Impossible de Créer la ville à l'emplacement désiré", "Erreur...");
                    return;
                }
                Ellipse ell = Dico_UnitToEll[uniteSelect];
                Dico_UnitToEll.Remove(uniteSelect);
                ell.Visibility = Visibility.Collapsed;
                ell = null;
                
                affichage_ville(true, j.getJoueurCourant(), ville);
                j.getJoueurCourant().getCivilisation().supprUnite(uniteSelect);
                uniteSelect = null;
                clearInterface();
                villeSelect = ville;
                updateSelectedTown(ville.getX(), ville.getY(), ville);
            }
        }

        /**
         * \fn Suggestion_Ville_Click
         * \brief event suggestion ville
         */
        unsafe private void Suggestion_Ville_Click(Object sender, RoutedEventArgs e)
        {
            int[][] sggs = j.getCarte().suggestionVille(uniteSelect.getX(), uniteSelect.getY(), uniteSelect.nbPtMvtRestant());
            Grid.SetColumn(suggestionville1, sggs[0][0]);
            Grid.SetRow(suggestionville1, sggs[0][1]);
            suggestionville1.Visibility = System.Windows.Visibility.Visible;

            Grid.SetColumn(suggestionville2, sggs[1][0]);
            Grid.SetRow(suggestionville2, sggs[1][1]);
            suggestionville2.Visibility = System.Windows.Visibility.Visible;

            Grid.SetColumn(suggestionville3, sggs[2][0]);
            Grid.SetRow(suggestionville3, sggs[2][1]);
            suggestionville3.Visibility = System.Windows.Visibility.Visible;
        }

        /**
         * \fn Creer_Unite_Click_1
         * \brief event creer unite
         */
        private void Creer_Unite_Click_1(object sender, RoutedEventArgs e)
        {
            int column = Grid.GetColumn(selectionRectangle);
            int row = Grid.GetRow(selectionRectangle);

            switch (creation_unite.SelectedIndex)
            {
                case 0 :
                    uniteSelect = (UniteImpl)j.getJoueurCourant().getCivilisation().creerEtudiant(column, row);
                    villeSelect.setMinerai(villeSelect.getMinerai() - CivilisationImpl.COUT_ETUDIANT);
                    break;
                case 1:
                    uniteSelect = (UniteImpl)j.getJoueurCourant().getCivilisation().creerEnseignant(column, row);
                    villeSelect.setMinerai(villeSelect.getMinerai() - CivilisationImpl.COUT_ENSEIGNANT);
                    break;
                case 2:
                    if (!j.getJoueurCourant().getCivilisation().aDirecteur())
                    {
                        uniteSelect = (UniteImpl)j.getJoueurCourant().getCivilisation().creerDirecteur(column, row);
                        villeSelect.setMinerai(villeSelect.getMinerai() - CivilisationImpl.COUT_DIRECTEUR);
                    }
                    break;
                default: return;
            }
            afficheUnite(uniteSelect, j.getJoueurCourant());
            Info_ville.Visibility = Visibility.Hidden;
            updateSelectedUnit(column, row, uniteSelect);
            
        }

        /**
         * \fn liste_chose_sur_pos_SelectionChanged_1
         * \brief event selection qq chose sur la liste des chose sur terrain
         */
        private void liste_chose_sur_pos_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            Info_Terrain.Visibility = Visibility.Hidden;
            int c = Grid.GetColumn(selectionRectangle);
            int r = Grid.GetRow(selectionRectangle);
            Ville v = j.getVillePosition(c, r);

            int moins = (v != null)? -1 : 0;//pour des pb d'index
            if ( v != null && liste_chose_sur_pos.SelectedIndex == 0)
            {
                updateSelectedTown(c, r, v);
                return;
            }
            if (liste_chose_sur_pos.SelectedIndex == -1)
            {
                return;
            }

            updateSelectedUnit(c, r, j.getUnitePosition(c,r)[liste_chose_sur_pos.SelectedIndex + moins]);
        }
    }
}
